(function () {

    function makeUrl(host, port, ssl) {
        var url = ssl ? 'wss://' : 'ws://';
        url += host;
        if (port) {
            url += ':' + port;
        }
        return url;
    }

    var _socket = function (host, port, ssl) {
        this.isclose = false;
        this.reuse = false;
        this.url = makeUrl(host, port, ssl);
        this.socket = new WebSocket(this.url);
        this.socket.binaryType = 'arraybuffer';
        var self = this;
        //注册socket事件
        this.socket.onmessage = function (event) {
            var listeners = self.listeners || {};
            var urlList = listeners[self.url] || [];
            urlList.forEach(function(e){
                e.onmessage(event);
            });
        }
        this.socket.onerror = function (error) {
            var listeners = self.listeners || {};
            var urlList = listeners[self.url] || [];
            urlList.forEach(function(e){
                e.onerror(error);
            });
        }
        this.socket.onclose = function () {
            var listeners = self.listeners || {};
            var urlList = listeners[self.url] || [];
            self.isclose = true;
            urlList.forEach(function(e){
                e.onclose();
            });
        }
        this.socket.onopen = function (event) { 
            var listeners = self.listeners || {};
            var urlList = listeners[self.url] || [];
            urlList.forEach(function(e){
                e.onopen(event, self.socket, false);
            });
        }
    }
    _socket.prototype = {
        bind: function (listener, fn) {
            var self = this;
            //绑定监听事件
            this.listeners = this.listeners || {};
            // var urlList = this.listeners[this.url] = this.listeners[this.url] || [];
            this.listeners[this.url] = [];
            this.listeners[this.url].push(listener);
            if (fn) {
                fn(self.socket,self.reuse);
            }
        }
    }

    //利用闭包的特性创建单例,同时符合惰性单例的特性
    _socket.getInstance = (function (host, port, ssl, cbs) {
        var instance = {};
        return function (host, port, ssl, cbs) {
            var url = makeUrl(host, port, ssl);
            var inst = instance[url] = null; //每次为空，则不使用缓存
            if (inst === null
                || !instance.hasOwnProperty(url)
                || inst['isclose']) {
                instance[url] = new _socket(host, port, ssl, cbs);
                inst = instance[url];
                inst.reuse = false;
            }else{
                inst.reuse = true;
            }
            return inst;
        }
    })();

    module.exports =  _socket;
    return _socket;
})()